#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <functional>
#include <pthread.h>
using namespace std;

static uint32_t number = 1;

template <typename T>
class Thread
{
    using func_t = function<void(T)>;

private:
    void EnableDetach()
    {
        std::cout << "线程被分离了" << std::endl;
        _isdetach = true;
    }
    void EnableRunning()
    {
        _isrunning = true;
    }

    static void *Routine(void *argv)
    {
        Thread<T> *self = static_cast<Thread<T> *>(argv);
        self->EnableRunning();
        if (self->_isdetach)
            self->Detach();
        self->_func(self->_data); // 回调处理
        return nullptr;
    }

public:
    Thread(func_t func, T Data)
        : _tid(0), _isrunning(false), _isdetach(false), _Data(Data), _func(func)
    {
        _name = "Thread - " + to_string(_number++);
    }

    void Detach()
    {
        if (_isdetach)
            return;
        int n = pthread_detach(_tid);
        if (n != 0)
        {
            cerr << "fail to detach" << strerror(n) << endl;
        }
        else
        {
            cout << "success to detach" << endl;
            _isdetach = true;
        }
    }

    void Join()
    {
        if (_isdetach)
        {
            cout << "线程已经分离，无法进行等待" << endl;
            return;
        }
        int n = pthread_join(_tid, &res);
        if (n != 0)
        {
            cerr << "fail to join" << strerror(n) << endl;
        }
        else
        {
            cout << "success to join" << endl;
        }
    }

    bool Start()
    {
        if (_isrunning)
            return false;
        int n = pthread_create(&tid, nullptr, Routine, this);
        if (n != 0)
        {
            cerr << "fail to create pthread" << strerror(n) << endl;
            return false;
        }
        else
        {
            cout << "success to create pthread" << strerror(n) << endl;
            return true;
        }
    }

    bool Stop()
    {
        if (!_isrunning)
            return false;
        int n = pthread_cancel(tid);
        if (n != 0)
        {
            cerr << "fail to Stop" << strerror(n) << endl;
            return false;
        }
        else
        {
            cout << "success to Stop" << endl;
            _isrunning = false;
            return true;
        }
    }

    ~Thread()
    {
    }

private:
    string _name;
    pthread_t _tid;
    bool _isrunning;
    bool _isdetach;
    T _Data;
    void *res;
    func_t _func;
};